/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.easoftware.code.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import javax.ejb.EJB;
import javax.inject.Inject;
import javax.inject.Named;
import net.easoftware.code.beans.MICreditRowDetail;
import net.easoftware.code.beans.QueryParameter;
import net.easoftware.code.beans.ReporteDetalleData;
import net.easoftware.code.beans.RepresentanteVentas;
import net.easoftware.code.beans.facade.Cliente8020Fc;
import net.easoftware.code.beans.facade.ClienteProvisionCuentas;
import net.easoftware.code.beans.facade.LineaNegocio;
import net.easoftware.code.beans.facade.MICredRubro;
import net.easoftware.code.beans.facade.UnidadNegocio;
import net.easoftware.code.beans.impl.ChequeRechazadoRow;
import net.easoftware.code.beans.impl.OrdenRetRow;
import net.easoftware.code.beans.impl.OrdenRow;
import net.easoftware.code.error.EaError;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

/**
 *
 * @author eder.herrera, EDiaz
 */
@Named("reporteDao")
public class ReporteDao implements Serializable {

    @Inject
    private DSManager dSManager;
    @EJB
    PersistenceEjb ejb;

    /**
     *
     * @param anio
     * @param mes
     * @param linea
     * @param unidad
     * @return
     * @throws EaError
     */
    public List<ChequeRechazadoRow> getChequesRechazados(Integer anio, Integer mes, Integer linea, Integer unidad) throws EaError {
        //getMIListChequesRechPopUp
        List<ChequeRechazadoRow> data = new LinkedList<>();
        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<ChequeRechazadoRow>> handler = new BeanListHandler<>(ChequeRechazadoRow.class);
            Object[] params = new Object[]{
                mes,
                anio,
                unidad,
                linea
            };
            data = qr.query("CALL getMIListChequesRechPopUp(?, ?, ?, ?);", handler, params);
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
        return data;
    }

    /**
     *
     * @param anio
     * @param mes
     * @param linea
     * @param unidad
     * @return
     * @throws EaError
     */
    public List<OrdenRow> getOrdenes(Integer anio, Integer mes, Integer linea, Integer unidad) throws EaError {
        List<OrdenRow> data = new LinkedList<>();
        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<OrdenRow>> handler = new BeanListHandler<>(OrdenRow.class);
            Object[] params = new Object[]{
                mes,
                anio,
                unidad,
                linea
            };
            data = qr.query("CALL getMIListOrdenesPopUp(?, ?, ?, ?);", handler, params);
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
        return data;
    }

    public List<OrdenRetRow> getOrdenesRet(Integer anio, Integer mes, Integer linea, Integer unidad) throws EaError {
        List<OrdenRetRow> data = new LinkedList<>();
        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<OrdenRetRow>> handler = new BeanListHandler<>(OrdenRetRow.class);
            Object[] params = new Object[]{
                mes,
                anio,
                unidad,
                linea
            };
            data = qr.query("CALL getMIListOrdenesRetenidasPopUp(?, ?, ?, ?);", handler, params);
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
        return data;
    }

    /**
     *
     * @param anio
     * @param mes
     * @param linea
     * @param unidad
     * @return
     */
    public List<ClienteProvisionCuentas> getProvisionCuentas(Integer anio, Integer mes, Integer linea, Integer unidad) throws EaError {
        List<ClienteProvisionCuentas> data = new LinkedList<>();
        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<ClienteProvisionCuentas>> handler = new BeanListHandler<>(ClienteProvisionCuentas.class);
            Object[] params = new Object[]{
                mes,
                anio,
                unidad,
                linea
            };
            data = qr.query("CALL getMIRepProvisionCuentasMalas(?, ?, ?, ?);", handler, params);
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
        return data;
    }

    /**
     * Genera reporte 8020
     *
     * @param anio
     * @param mes
     * @param linea
     * @param unidad
     * @return
     */
    public List<Cliente8020Fc> getClientes8020(Integer anio, Integer mes, Integer linea, Integer unidad) throws EaError {
        List<Cliente8020Fc> data = new LinkedList<>();
        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<Cliente8020Fc>> handler = new BeanListHandler<>(Cliente8020Fc.class);
            Object[] params = new Object[]{
                mes,
                anio,
                unidad,
                linea
            };
            data = qr.query("CALL getMIRep8020Cuentas(?, ?, ?, ?);", handler, params);
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el grid principal", ex);
        }
        return data;
    }

    /**
     * Obteiene la informacion para todos los paises
     *
     * @param mes
     * @param anio
     * @return
     * @throws EaError
     */
    public List<MICreditRowDetail> getMICreditGridPaisesRows(Integer mes, Integer anio, Integer idPerfil) throws EaError {
        List<MICreditRowDetail> data = new LinkedList<>();
        List<Object[]> l = (List<Object[]>) ejb.doSp("Call getMIPaisesGrid(?,?,?);", null,
                new QueryParameter[]{new QueryParameter("1", mes),
            new QueryParameter("2", anio),
            new QueryParameter("3", idPerfil)}, false);

        for (Object[] rw : l) {
            MICreditRowDetail rb = new MICreditRowDetail();
            rb.setGrid((Integer) rw[0]);
            rb.setOrden(Integer.valueOf(rw[1].toString()));
            rb.setRubro(rw[2] != null ? rw[2].toString() : "");
            rb.setUnidadNegocio(rw[3] != null ? Integer.valueOf(rw[3].toString()) : 0);
            rb.setValor(rw[5] != null ? rw[5].toString() : "-");
            rb.setAnio(anio);
            rb.setMes(mes);
            data.add(rb);
        }

        return data;
    }

    /**
     * Obtiene la informacion para los agentes
     *
     * @param mes
     * @param anio
     * @param unidadNeg
     * @param lineaNeg
     * @return
     * @throws EaError
     *
     */
    public List<MICreditRowDetail> getMICreditRepVentasGridRows(Integer mes, Integer anio, Integer unidadNeg, Integer lineaNeg) throws EaError {
        List<MICreditRowDetail> data = new LinkedList<>();
        List<Object[]> l = (List<Object[]>) ejb.doSp("Call getMIRepVentasGrid(?,?,?,?);", null,
                new QueryParameter[]{new QueryParameter("1", mes),
            new QueryParameter("2", anio),
            new QueryParameter("3", unidadNeg),
            new QueryParameter("4", lineaNeg)}, false);

        for (Object[] rw : l) {
            MICreditRowDetail rb = new MICreditRowDetail();
            rb.setGrid((Integer) rw[0]);
            rb.setOrden(Integer.valueOf(rw[1].toString()));
            rb.setRubro(rw[2] != null ? rw[2].toString() : "");
            rb.setRepventas(rw[3].toString());
            rb.setValor(rw[4] != null ? rw[4].toString() : "-");
            data.add(rb);
        }

        return data;
    }

    /**
     * Obtiene la informacion para el grid principal
     *
     * @param mes
     * @param anio
     * @param unidadNeg
     * @param lineaNeg
     * @return
     * @throws EaError
     *
     */
    public List<MICreditRowDetail> getMICreditGridRows(Integer mes, Integer anio, Integer unidadNeg, Integer lineaNeg, Integer idPerfil) throws EaError {
        List<MICreditRowDetail> data = new LinkedList<>();
        List<Object[]> l = (List<Object[]>) ejb.doSp("Call getMIPrincipalGrid(?,?,?,?,?);", null,
                new QueryParameter[]{new QueryParameter("1", mes),
            new QueryParameter("2", anio),
            new QueryParameter("3", unidadNeg),
            new QueryParameter("4", lineaNeg),
            new QueryParameter("5", idPerfil)}, false);

        for (Object[] rw : l) {
            MICreditRowDetail rb = new MICreditRowDetail();
            rb.setGrid((Integer) rw[0]);
            rb.setOrden(Integer.valueOf(rw[1].toString()));
            rb.setRubro(rw[2] != null ? rw[2].toString() : "");
            rb.setUnidadNegocio(rw[3] != null ? Integer.valueOf(rw[3].toString()) : lineaNeg);
            rb.setLineaNegocio(rw[4] != null ? Integer.valueOf(rw[4].toString()) : unidadNeg);
            rb.setValor(rw[5] != null ? rw[5].toString() : "-");
            data.add(rb);
        }

        return data;
    }

    /**
     * Rubros a contabilizar
     *
     * @return
     * @throws EaError
     */
    public List<MICredRubro> getRubrosMICredit() throws EaError {
        List<MICredRubro> r = new LinkedList<>();
        List<Object[]> l = (List<Object[]>) ejb.doSp("Call getMIRubrosCat();", null, new QueryParameter[]{}, false);

        for (Object[] rw : l) {
            MICredRubro rb = new MICredRubro();
            rb.setGrid((Integer) rw[0]);
            rb.setRubro(rw[1].toString());
            rb.setPopup(rw[2] != null ? rw[2].toString() : "");
            rb.setSumarhor(rw[3] != null ? rw[3].toString() : "0");
            r.add(rb);
        }

        return r;
    }

    /**
     * Rubros a contabilizar
     *
     * @return
     * @throws EaError
     */
    public List<MICredRubro> getRubrosPaisesMICredit() throws EaError {
        List<MICredRubro> r = new LinkedList<>();
        List<Object[]> l = (List<Object[]>) ejb.doSp("Call getMIRubrosCatPaises();", null, new QueryParameter[]{}, false);

        for (Object[] rw : l) {
            MICredRubro rb = new MICredRubro();
            rb.setGrid((Integer) rw[0]);
            rb.setRubro(rw[1].toString());
            rb.setPopup(rw[2] != null ? rw[2].toString() : "");
            rb.setSumarhor(rw[3] != null ? rw[3].toString() : "0");
            r.add(rb);
        }

        return r;
    }

    /**
     * Rubros a contabilizar
     *
     * @return
     * @throws EaError
     */
    public List<MICredRubro> getRubrosRepVentasMICredit() throws EaError {
        List<MICredRubro> r = new LinkedList<>();
        List<Object[]> l = (List<Object[]>) ejb.doSp("Call getMIRubrosRepVentasCat();", null, new QueryParameter[]{}, false);

        for (Object[] rw : l) {
            MICredRubro rb = new MICredRubro();
            rb.setGrid((Integer) rw[0]);
            rb.setRubro(rw[1].toString());
            rb.setPopup(rw[2] != null ? rw[2].toString() : "");
            rb.setSumarhor(rw[3] != null ? rw[3].toString() : "0");;
            r.add(rb);
        }

        return r;
    }

    /**
     * Representantes de ventas contenidos en las cargas del mes y a;o indicados
     *
     * @param mes
     * @param anio
     * @param unidad
     * @param linea
     * @return
     * @throws EaError
     */
    public List<RepresentanteVentas> getRepresentantesVentas(Integer mes, Integer anio, Integer unidad, Integer linea) throws EaError {
        List<RepresentanteVentas> r = new LinkedList<>();
        List<String> l = (List<String>) ejb.doSp("Call getMIRepVentas(?,?,?,?);", null,
                new QueryParameter[]{
            new QueryParameter("1", mes),
            new QueryParameter("2", anio),
            new QueryParameter("3", unidad),
            new QueryParameter("4", linea)}, false);

        for (String rw : l) {
            RepresentanteVentas rb = new RepresentanteVentas();
            rb.setRepventas(rw);
            r.add(rb);
        }

        return r;
    }

    /**
     *
     * @param anioInicio
     * @param mesInicio
     * @param anioFin
     * @param mesFin
     * @param unidadNegocio
     * @param lineaNegocio
     * @return
     * @throws EaError
     */
    public List<ReporteDetalleData> obtenerReporteData(Integer anioInicio, Integer mesInicio, Integer anioFin, Integer mesFin, Integer unidadNegocio, Integer lineaNegocio) throws EaError {
        List<ReporteDetalleData> reporteDetalle = new LinkedList<>();
        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());

            ResultSetHandler<List<ReporteDetalleData>> handler = new BeanListHandler<>(ReporteDetalleData.class);
            Object[] params = new Object[]{
                anioInicio,
                mesInicio,
                anioFin,
                mesFin,
                unidadNegocio,
                lineaNegocio
            };
            if (lineaNegocio == 0) {
                reporteDetalle = qr.query("CALL ObtenerReporte(?, ?, ?, ?, ?, ?);", handler, params);
            } else {
                reporteDetalle = qr.query("CALL ObtenerDetalleReporte(?, ?, ?, ?, ?, ?);", handler, params);
            }
        }
        catch (SQLException ex) {
            throw new EaError("Error al obtener el reporte", ex);
        }

        return reporteDetalle;
    }

    /**
     *
     * @return @throws EaError
     */
    public List<UnidadNegocio> obtenerUnidadesDeNegocio() throws EaError {
        List<UnidadNegocio> unidadesDeNegocio = new LinkedList<>();

        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<UnidadNegocio>> handler = new BeanListHandler<>(UnidadNegocio.class);
            unidadesDeNegocio = qr.query("CALL ObtenerUnidadesDeNegocio();", handler);
        }
        catch (Exception ex) {
            throw new EaError("Error al obtener todas las unidades de negocio", ex);
        }

        return unidadesDeNegocio;
    }

    /**
     *
     * @return @throws EaError
     */
    public List<LineaNegocio> obtenerLineasDeNegocio() throws EaError {
        List<LineaNegocio> lineasDeNegocio = new LinkedList<>();

        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<List<LineaNegocio>> handler = new BeanListHandler<>(LineaNegocio.class);
            lineasDeNegocio = qr.query("CALL ObtenerLineasDeNegocio();", handler);
        }
        catch (Exception ex) {
            throw new EaError("Error al obtener todas las lineas de negocio", ex);
        }

        return lineasDeNegocio;
    }

    /**
     *
     * @param id
     * @return
     * @throws EaError
     */
    public LineaNegocio obtenerLineaNegocio(int id) throws EaError {
        LineaNegocio lineaNegocio = new LineaNegocio();

        try {
            QueryRunner qr = new QueryRunner(dSManager.getDs());
            ResultSetHandler<LineaNegocio> handler = new BeanHandler<>(LineaNegocio.class);
            lineaNegocio = qr.query("CALL ObtenerLineaDeNegocioPorId(?);", handler, id);
        }
        catch (Exception ex) {
            throw new EaError("Error al obtener linea de negocio con id: " + id, ex);
        }

        return lineaNegocio;
    }
}
